function createShader(gl, type, source) {
    // 2.1创建对应类型的shader
    const shader = gl.createShader(type);
    // 2.2给shader添加数据源
    gl.shaderSource(shader, source);
    // 2.3编译shader
    gl.compileShader(shader);

    const success = gl.getShaderParameter(shader, gl.COMPILE_STATUS);
    if (success) {
        return shader;
    }
    gl.deleteShader(shader);
}

function createProgram(gl, vertexShader, fragmentShader) {
    // 3.1创建program
    const program = gl.createProgram();
    // 3.2添加顶点着色器
    gl.attachShader(program, vertexShader);
    gl.attachShader(program, fragmentShader);
    // 3.3添加片段着色器
    gl.linkProgram(program);
    const success = gl.getProgramParameter(program, gl.LINK_STATUS);
    if (success) {
        return program;
    }
    console.log(gl.getProgramInfoLog(program));
    gl.deleteProgram(program);
}

// 用参数生成矩形顶点并写进缓冲

function setRectangle(gl, x, y, width, height) {

    var x1 = x;
    var x2 = x + width;
    var y1 = y;
    var y2 = y + height;

    // 注意: gl.bufferData(gl.ARRAY_BUFFER, ...) 将会影响到
    // 当前绑定点`ARRAY_BUFFER`的绑定缓冲
    // 目前我们只有一个缓冲，如果我们有多个缓冲
    // 我们需要先将所需缓冲绑定到`ARRAY_BUFFER`

    gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
        x1, y1,
        x2, y1,
        x1, y2,
        x1, y2,
        x2, y1,
        x2, y2
    ]), gl.STATIC_DRAW);
}

// 返回 0 到 range 范围内的随机整数
function randomInt(range) {
    return Math.floor(Math.random() * range);
}

function main() {
    // 1.创建glcontext

    var canvas = document.querySelector('#glcanvas');
    var gl = canvas.getContext('webgl');
    if (!gl) {
        return;
    }

    // 2.创建顶点着色器和片段着色器
    // 获取GLSL着色器strings
    const vertexShaderSource = document.querySelector("#vertex-shader").text;
    const fragmentShaderSource = document.querySelector("#fragment-shader").text;
    const vertexShader = createShader(gl, gl.VERTEX_SHADER, vertexShaderSource);
    const fragmentShader = createShader(gl, gl.FRAGMENT_SHADER, fragmentShaderSource);
    // 3.链接两个着色器到program
    const program = createProgram(gl, vertexShader, fragmentShader);

    // 4.告诉顶点数据的位置在哪儿
    const positionAttriabute = gl.getAttribLocation(program, "a_position");
    var resolutionUniformLocation = gl.getUniformLocation(program, "u_resolution");
    var colorUniformLocation = gl.getUniformLocation(program, "u_color");

    // 5.初始化缓冲区
    // 5.1创建缓冲区
    const positionBuffer = gl.createBuffer();

    //5.2将positionBuffer绑定到ARRAY_BUFFER(可以将其视为ARRAY_BUFFER=PositionBuffer)
    gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);

    // 5.3创建一个包含三角形顶点的数组
    // const positions = [
    //     -0.5, -0.5,
    //     -0.5, 0.5,
    //     0.5, 0.5,
    //     0.5, 0.5,
    //     -0.5, -0.5,
    //     0.5, -0.5
    // ];
    // var positions = [
    //     10, 20,
    //     80, 20,
    //     10, 30,
    //     10, 30,
    //     80, 20,
    //     80, 30,
    // ];
    // 5.4将数据写入缓冲区,通过绑定点向缓冲区中存放数据
    // gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positions), gl.STATIC_DRAW);

    // 6.绘制
    // 重置画布大小
    webglUtils.resizeCanvasToDisplaySize(gl.canvas);
    // 6.2.1设置视口
    gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);
    // 6.2.2清空画布
    gl.clearColor(1, 0, 0, 0);
    gl.clear(gl.COLOR_BUFFER_BIT);
    // 6.2.3告诉它用我们之前写好的着色程序（一个着色器对）
    gl.useProgram(program);
    // 6.2.4启用属性
    gl.enableVertexAttribArray(positionAttriabute);
    // 6.2.5绑定数据，告诉属性如何从positionBuffer（ARRAY_BUFFER）中获取数据
    gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);

    var size = 2;          // 每次迭代的组件数为2
    var type = gl.FLOAT;   // 数据为32位浮点数
    var normalize = false; // 不对数据进行归一化
    var stride = 0;        // 0 = 每次迭代移动 size * sizeof(type) 以获取下一个位置
    var offset = 0;        // 从缓冲区的开头开始
    gl.vertexAttribPointer(
        positionAttriabute, size, type, normalize, stride, offset);
    gl.uniform2f(resolutionUniformLocation, gl.canvas.width, gl.canvas.height);
    var primitiveType = gl.TRIANGLES;
    var offset = 0;
    var count = 6;
    // 6.2.6绘制

    // 绘制矩形
    for (var ii = 0; ii < 5; ++ii) {
        // 设置矩形位置
        setRectangle(gl, randomInt(300), randomInt(300), randomInt(300), randomInt(300));
        // 设置矩形颜色
        gl.uniform4f(colorUniformLocation, Math.random(), Math.random(), Math.random(), 1);
        // 绘制矩形
        gl.drawArrays(gl.TRIANGLES, 0, 6);
    }

    // 绘制圆形
    for (var ii = 0; ii < 20; ++ii) {
        const vertices = [];
        const centerX = randomInt(640);
        const centerY = randomInt(640);
        // 中心点
        vertices.push(centerX, centerY);

        const numSegments = randomInt(50); // 圆形被分成的段数
        const radius = randomInt(100); // 圆形半径

        for (let i = 0; i <= numSegments; i++) {
            const theta = (i / numSegments) * (2 * Math.PI);
            const x = centerX + radius * Math.cos(theta);
            const y = centerY + radius * Math.sin(theta);
            vertices.push(x, y);
        }

        gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
        gl.uniform4f(colorUniformLocation, Math.random(), Math.random(), Math.random(), 1);
        // 绘制矩形
        gl.drawArrays(gl.TRIANGLE_FAN, 0, numSegments + 2);
    }
}

main()